/* Programa que le dois vetores fornecidos pelo usuario, e imprime os vetores originais, os vetores normalizados e
 * a soma dos vetores caso eles tenham a mesma dimensao.
 * Autor: Jose Geraldo de Carvalho Pereira	RA: 482536 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct vetor Vetor;
struct vetor {
	int dimensao;
	double *coordenadas;
};

int leVetor(Vetor *vetor){
	// Funcao que le os dados de um vetor fornecido pelo usuario e atualizada o parametro 'vetor'
	// Caso a leitura seja realizada com sucesso a funcao retorna 0
	// Caso ocorra algum erro, o erro sera impresso e a funcao retornara 1
	
	int i;

	//leitura da dimensao do vetor (deve ser maior que 0) 
	printf("Dimensao do vetor (D>0): ");
	scanf("%d", &vetor->dimensao);
	if (vetor->dimensao < 1){
		printf("Erro: Dimensao %d do vetor invalida. ",vetor->dimensao);
	       	printf("Dimensao deve ser MAIOR que 0.\n\n");
		return -1; //erro
	}

	//alocacao dinamica de um vetor para armazenar as coordenadas
	vetor->coordenadas = malloc(vetor->dimensao * sizeof(double));
	if (vetor->coordenadas == NULL){
		printf("Erro na alocacao de memoria na leitura do vetor.\n\n");
		return -1; //erro
	}

	//leitura das coordenadas
	for (i=0; i < vetor->dimensao; i++){
		printf("Coordenada %d do vetor: ", i+1);
		scanf("%lf", &vetor->coordenadas[i]);
	}
	printf("\n");
	return 0; //sucesso
}	

void imprimeVetor(Vetor *vetor){
	//Funcao que imprime os dados (dimensao e coordenadas) de um vetor
	
	int i;
	printf("Dimensao %d\n", vetor->dimensao);
	printf("Coordenadas ( ");
	for (i=0; i < vetor->dimensao; i++)
		printf("%.3f ", vetor->coordenadas[i]);  
	printf(")\n\n");
}

Vetor somaVetores(Vetor *vetor1, Vetor *vetor2) {
	//Funcao que soma dois vetores passados como parametro
	//Caso os vetores sejam somados com sucesso o vetor contendo o resultado da soma sera retornado
	//Caso a soma falhe devido aos vetores terem dimensoes diferentes ou caso ocorra um erro na 
	//alocacao de memoria, a funcao imprime o erro e retornara um vetor com dimensao 0
	
	Vetor soma;
	int i;
	
	//testa se os dimensoes sao iguais
	if (vetor1->dimensao != vetor2->dimensao){
		printf("Nao foi possivel realizar a soma.\n");
		printf("Para somar dois vetores eles precisam ter dimensoes iguais.\n\n");
		soma.dimensao = 0; //indica erro 
		return soma;
	}

	//alocacao de memoria para o vetor soma	
	soma.dimensao = vetor1->dimensao;
	soma.coordenadas = malloc(soma.dimensao * sizeof(double));
	if (soma.coordenadas == NULL){
		printf("Erro na alocacao de memoria na soma dos vetores.\n\n");
		soma.dimensao = 0; //indica erro
		return soma;
	}
	
	//realiza a soma das coordenadas
	for (i=0; i < soma.dimensao; i++)
		soma.coordenadas[i] = vetor1->coordenadas[i] + vetor2->coordenadas[i];
	
	return soma;
}

Vetor normalizaVetor(Vetor *vetor) {
	//Funcao que normaliza um vetor e retorna o vetor normalizado
	//Caso ocorra uma falha na alocacao dinamica o vetor retornado tera dimensao 0
	
	Vetor normalizado;
	double modulo = 0;
	int i;

	normalizado.dimensao = vetor->dimensao;
	normalizado.coordenadas = malloc(normalizado.dimensao * sizeof(double));
	if (normalizado.coordenadas == NULL){
		printf("Erro na alocacao de memoria na normalizacao do vetor.\n\n");
		normalizado.dimensao = 0; //indica erro
		return normalizado;
	}

	//calcula o modulo do vetor original para realizar a normalizacao
	for (i=0; i < vetor->dimensao; i++)
		modulo += (vetor->coordenadas[i] * vetor->coordenadas[i]);
	modulo = sqrt(modulo);

	//calcula as coordenadas normalizadas do vetor
	for (i=0; i < normalizado.dimensao; i++)
		normalizado.coordenadas[i] = vetor->coordenadas[i]/modulo;

	return normalizado;
		
}	

int main(){
	Vetor vetor1, vetor2, vetorSoma, vetorNormalizado1, vetorNormalizado2;

	printf("Dados do vetor 1\n");
	while (leVetor(&vetor1) != 0)	//repete a leitura do vetor ate que a leitura seja feita com sucesso
		;

	printf("Dados do vetor 2\n");
	while (leVetor(&vetor2) != 0)	//repete a leitura do vetor ate que a leitura seja feita com sucesso
		;
	
	printf("--------------------\n\n");	

	printf("Vetor 1 [original]\n");
	imprimeVetor(&vetor1);
	
	printf("Vetor 2 [original]\n");
	imprimeVetor(&vetor2);
	
	printf("Soma dos vetores 1 e 2\n");
	vetorSoma = somaVetores(&vetor1, &vetor2);
	if (vetorSoma.dimensao != 0)	//caso a soma nao seja realizada com sucesso a dimensao sera 0 e o vetor nao sera impresso
		imprimeVetor(&vetorSoma);

	printf("Vetor 1 [normalizado]\n");
	vetorNormalizado1 = normalizaVetor(&vetor1);
	if (vetorNormalizado1.dimensao != 0)	//caso a normalizacao nao seja realizada com sucesso a dimensao sera 0 e o vetor nao sera impresso
		imprimeVetor(&vetorNormalizado1);

	printf("Vetor 2 [normalizado]\n");
	vetorNormalizado2 = normalizaVetor(&vetor2);
	if (vetorNormalizado2.dimensao != 0)	//caso a normalizacao nao seja realizada com sucesso a dimensao sera 0 e o vetor nao sera impresso
		imprimeVetor(&vetorNormalizado2);

	system("pause");
	return 0;
}
